﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using l1cs.server.templates;
using MySql.Data.MySqlClient;
using l1cs.server.utils;
using System.Collections;

namespace l1cs.server.datatables
{
    public class CastleTable
    {
        private static Logger _log = Logger.getLogger( typeof( CastleTable ).FullName );

        private static CastleTable _instance;

        /// <summary>
        /// スレッドセーフなハッシュテーブル
        /// </summary>
        private Hashtable _castles = Hashtable.Synchronized( new Hashtable() );

        public static CastleTable getInstance()
        {
            if ( _instance == null )
            {
                _instance = new CastleTable();
            }
            return _instance;
        }

        private CastleTable()
        {/*TTOK*/
            String sqlstr = "SELECT * FROM castle";
            using ( MySqlWrapper wrapper = new MySqlWrapper() )
            {
                foreach ( DataRow item in wrapper.GetDataTable( sqlstr ).Rows )
                {
                    int castle_id = SqlUtils.toInt( item["castle_id"] );
                    String name = Convert.ToString( item["name"] );
                    L1Castle castle = new L1Castle( castle_id, name );
                    castle.setWarTime( (DateTime)SqlUtils.toDateTime( item["war_time"] ) ); // Not NULL
                    castle.setTaxRate( SqlUtils.toInt( item["tax_rate"] ) );
                    castle.setPublicMoney( SqlUtils.toInt( item["public_money"] ) );

                    _castles[castle.getId()] = castle;
                }
            }
        }

        /// <summary>
        /// 城一覧を返す。
        /// </summary>
        /// <returns>城一覧のコレクション</returns>
        public L1Castle[] getCastleTableList()
        {/*TTOK*/
            // TODO 優先度5 Hashtableのコピー渡しよりいい方法はないか？
            L1Castle[] ret = new L1Castle[_castles.Count];
            _castles.Values.CopyTo( ret, 0 );
            return ret;
        }

        /// <summary>
        /// 指定されたIDの城情報を返す。
        /// </summary>
        /// <param name="id">城ID</param>
        /// <returns>城情報</returns>
        public L1Castle getCastleTable( int id )
        {/*TTOK*/
            // HashTableはキーがない場合はNULLとなる
            return (L1Castle)_castles[id];
        }

        /// <summary>
        /// 城情報を更新する。
        /// </summary>
        /// <param name="castle">更新する城情報</param>
        public void updateCastle( L1Castle castle )
        {/*TTOK*/
            String sqlstr = "UPDATE castle SET " +
                            "name            = ?1, " +
                            "war_time        = ?2, " +
                            "tax_rate        = ?3, " +
                            "public_money    = ?4 " +
                            "WHERE castle_id = ?5";
            using ( MySqlWrapper wrapper = new MySqlWrapper() )
            {
                MySqlCommand cmd = new MySqlCommand( sqlstr );
                cmd.Parameters.Add( "?1", MySqlDbType.String ).Value = castle.getName();
                cmd.Parameters.Add( "?2", MySqlDbType.DateTime ).Value = castle.getWarTime();
                cmd.Parameters.Add( "?3", MySqlDbType.Int32 ).Value = castle.getTaxRate();
                cmd.Parameters.Add( "?4", MySqlDbType.Int32 ).Value = castle.getPublicMoney();
                cmd.Parameters.Add( "?5", MySqlDbType.Int32 ).Value = castle.getId();
                wrapper.ExecNonQuery( cmd );
            }
            _castles[castle.getId()] = castle;
        }
    }
}
